home *** CD-ROM | disk | FTP | other *** search
- /* -*- C -*-
- * GETKEY.C
- *
- * (c)Copyright 1990 by Tobias Ferber, All Rights Reserved.
- */
-
- /* $VER: $Id: getkey.c,v 1.2 1995/07/02 22:21:44 tf Exp $ */
-
- #include <stdio.h>
- #include "getkey.h"
-
-
- /* Note: Turbo C Version 1.0 can *NOT* read from non-buffered streams */
-
- #if defined(__TURBOC__)
- #undef getkey
- #include <conio.h>
- int getkey(void) { return getch(); }
-
-
- #elif defined(GNUDOS)
-
- int getkey(void)
- /* read from a non-buffered, binary opened console stream */
- {
- FILE *con; /* the console stream */
- int key;
-
- /* you *MUST* open the console in binary mode for DJGPP
- * in order to really get a non-buffered stream via setvbuf()! */
-
- if( con= fopen(CONSOLENAME,"rb") )
- {
- setvbuf(con,0L,_IONBF,0L); /* better than setbuf(con,0L); ? */
-
- if(ferror(con))
- clearerr(con);
-
- fflush(con);
-
- key= (int)fgetc(con);
-
- fclose(con);
- }
- else key= stdin ? (int)fgetc(stdin) : 0;
-
- return key;
- }
-
-
- #elif defined(__MSDOS__)
- #include <dos.h>
-
- /*
- * The following stuff is implemented in the c.lib of DJGPP and is
- * Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
- *
- * .globl _getkey
- * _getkey:
- * pushl %ebx
- * pushl %esi
- * pushl %edi
- * movb $0,%ah
- * int $0x16
- * cmpb $0,%al
- * jnz L1
- * movb %ah,%al
- * movb $1,%ah
- * jmp L2
- * L1:
- * movb $0,%ah
- * L2:
- * andl $0xffff,%eax
- * popl %edi
- * popl %esi
- * popl %ebx
- * ret
- */
-
- int getkey(void)
- /* returns the keycode of the last pressed key using BIOS */
- {
- union REGS regs; /* defined in <dos.h> */
- regs.h.ah= 0x10; /* get MF-II keycode function # */
- int86(0x16,®s,®s); /* int 16h -> keycode in regs.x.ax */
- return (unsigned short)regs.x.ax;
- }
-
-
- #elif defined(AMIGA)
-
- #include <exec/types.h>
- #include <exec/ports.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
-
- /*
- * Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
- * Finkel. This function will send a packet of the given type to the Message
- * Port supplied.
- */
-
- typedef struct StandardPacket StandardPacket;
-
- long
- SendPacket(pid, action, args, nargs)
- struct MsgPort *pid; /* process indentifier ... (handler's message port) */
- long action; /* packet type ... (what you want handler to do) */
- long *args; /* a pointer to an argument list */
- long nargs; /* number of arguments in list */
- {
- struct MsgPort *replyport;
- StandardPacket *packet;
- long count, *pargs, res1;
-
- replyport= (struct MsgPort *)CreatePort(NULL, 0L);
- if (!replyport)
- return(0);
-
- /* Allocate space for a packet, make it public and clear it */
-
- packet = (StandardPacket *)
- AllocMem(sizeof(StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
-
- if (!packet) {
- DeletePort(replyport);
- return(0);
- }
- packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
- packet->sp_Pkt.dp_Port = replyport;
- packet->sp_Pkt.dp_Type = action;
-
- /* copy the args into the packet */
-
- pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
- for (count = 0; count < nargs; count++)
- pargs[count] = args[count];
-
- PutMsg(pid, &packet->sp_Msg); /* send packet */
-
- WaitPort(replyport);
- GetMsg(replyport);
-
- res1 = packet->sp_Pkt.dp_Res1;
-
- FreeMem(packet, sizeof(StandardPacket));
- DeletePort(replyport);
-
- return (res1);
- }
-
- int getkey(void)
- {
- int key= 0; /* the one we're going to return */
- BPTR con; /* BCPL pointer to a struct FileHandle */
-
- /* We must use Open() here -- not Input() -- because last may
- * be redirected. */
-
- con= Open( CONSOLENAME, MODE_OLDFILE );
-
- if( BADDR(con) && IsInteractive(con) )
- {
- struct MsgPort *mp;
- long arg[1], res;
-
- mp = ((struct FileHandle *)(BADDR(con)))->fh_Type;
- arg[0]= -1L; /* make it RAW */
- res= SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
-
- if(res)
- {
- char buffer[4]; /* just to be sure... */
- long actualLength; /* return value */
-
- /* The value returned by Read() is the length of the information
- * actually read. So when 'actualLength' is > 0, then it is the
- * number of characters read. A value of zero means that the
- * end-of-file has been reached. Errors are indicated by a value
- * of -1. Note: Read is an unbuffered routine. */
-
- actualLength = Read( con, buffer, (long)sizeof(buffer)-1 );
- /* 1 extra (for the bugs) */
- if(actualLength > 0)
- key= (int)buffer[0];
-
- arg[0]= 0L; /* make it COOKED */
- (void)SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
- }
-
- /* Note that we must close 'con' again, whereas Input() must NEVER
- * be closed. */
-
- Close(con);
- }
-
- if(!key)
- key= getchar(); /* just to be sure... */
-
- return key;
- }
-
-
- #elif defined(unix) || defined(__alpha)
-
- #include <curses.h>
-
- int getkey(void)
- {
- char c;
-
- #ifdef OBSOLETE
-
- /* try /dev/tty. If that doesn't work, use file descriptor 2,
- * which in Unix is usually attached to the screen, but also
- * usually lets you read from the keyboard. */
-
- int tty= open("/dev/tty", 0);
- if(tty < 0)
- tty= 2;
-
- { int result;
- do {
- result= read(tty, &c, sizeof(char));
- } while( result != 1 );
- }
-
- if(tty!=2)
- close(tty);
-
- #else /* POSIX */
-
- initscr();
- savetty();
- cbreak();
- noecho();
- c= getch();
- resetty();
- endwin();
-
- #endif
-
- return c;
- }
-
- #endif /* which machine? */
-
-
- #ifdef TEST
- #include <stdlib.h>
-
- main(int argc, char **argv)
- {
- int err= 0;
-
- if(argc==2)
- {
- char *s= argv[1];
- do {
- char c= getkey();
- #ifdef DEBUG
- printf("getkey() returned 0x%02x\n",c)
- #endif
- for(err=0; s[err]!='\0'; err++)
- if(c==s[err])
- break;
- } while(s[err]=='\0');
- }
- else
- { puts("GETKEY [keys]\n\n"
- "GetKey wartet auf eine der Tasten in 'keys' und gibt den\n"
- "Index der gedrueckten Taste aus 'keys' im Errorlevel zurueck");
- }
- #ifdef DEBUG
- printf("errorlevel=%d\n",err);
- #endif
- exit(err);
- }
- #endif /* TEST */
-